<?php
// +----------------------------------------------------------------------
// | 有小象汇 自研正版源码 赋能开发者
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 http://www.uxphp.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 有小象汇并不是自由软件，未经许可不能去掉有小象汇相关版权
// +----------------------------------------------------------------------
// | Author:  有小象汇
// +----------------------------------------------------------------------

namespace app\services\car;


use app\dao\car\CarOrderReturnDao;
use app\model\car\CarInfo;
use app\model\car\CarOrder;
use app\model\car\CarOrderReturn;
use app\model\car\CarOrderTake;
use app\model\car\CarType;
use app\services\BaseServices;
use think\exception\ValidateException;
use think\facade\Db;
use app\api\controller\v3\SampleController;
use app\api\controller\v3\WxPayController;
use crmeb\services\app\MiniProgramService;

/**
 * Class CarOrderReturnServices
 * @package app\services\car
 */
class CarOrderReturnServices extends BaseServices
{
    public function __construct(CarOrderReturnDao $dao)
    {
        $this->dao = $dao;
    }

    // 生成还车单号
    public function getReturnNo()
    {
        $date = date('YmdHis', time()) . rand(10, 99);
        return 'HC' . $date;
    }


    /**
     * 获取逾期弹框信息
     * @param $data
     * @param $op_user
     * @param $op_user_type
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get_yuqi_data($data, $op_user, $op_user_type)
    {
        /** @var CarOrderServices $orderServices */
        $list = [];
        $orderServices = app()->make(CarOrderServices::class);
        $orderInfo = CarOrder::find($data['order_id']);
        $orderInfo = $orderInfo ? $orderInfo->toArray() : [];
        if (!$orderInfo) throw new ValidateException('未查询到订单信息');
        if ($data['type'] == "yuqi") {
            //逾期时间
            $yq_time = bcmul($data['is_yq'], 86400);
            $yq_time = bcadd($yq_time, $orderInfo['end_time']);
            $return_time = $yq_time;
            $check_yq = 0;
            // 判断用户是否超时还车
            if ($data['is_yq'] > 0) {
                $check_yq = 1;
            }
            if ($check_yq == 1) {
                $over_start_time = $orderInfo['end_time']; // 超时开始时间（订单结束时间）
                $over_end_time = $return_time;  // 超时结束时间（实际还车时间）
                $over_day = intval(($over_end_time - $over_start_time) / 86400);
//            $over_hour = round(($over_end_time - $over_start_time) % 86400 / 3600, 2);
                $over_hour = round(($over_end_time - $over_start_time) / 3600, 2);
                $over_car_fee = $orderServices->carFee3($orderInfo['type_id'], $over_start_time, $return_time, $over_hour, $data['is_yq']); // 超时租车费
                $kou = bcadd($over_car_fee, $data['ss_car_price'], 2);
                if ($orderInfo['deposit'] < $kou) throw new ValidateException('车损合计与逾期超时费总和不得超过车辆押金!');
                $over_base_service_fee = $orderServices->baseServiceFee($orderInfo['type_id'], $over_start_time, $over_end_time); // 超时基础服务费
                $service = $orderServices->getcarService($orderInfo['type_id'], $over_start_time, $over_end_time);
                $over_car_service_fee = 0;// 超时保险费
                foreach ($service as $ser) {
                    if ($orderInfo['car_service_id']) {
                        if ($ser['id'] == $orderInfo['car_service_id']) {
                            $over_car_service_fee = $ser['price'];
                            break;
                        }
                    }
                }
                $over_return_fee = bcadd($over_car_fee, $over_base_service_fee, 2);
                $over_return_fee = bcadd($over_return_fee, $over_car_service_fee, 2);//逾期费用
                $return_deposit_fee = bcsub($orderInfo['deposit'], $over_car_fee, 2);
                $return_deposit_fee = bcsub($return_deposit_fee, $data['ss_car_price'], 2);
                $list['over_return_fee'] = $over_car_fee;
                $list['early_return_fee'] = 0;
                $list['ss_car_price'] = $data['ss_car_price'];
                $list['deposit'] = $orderInfo['deposit'];
                $list['return_deposit_fee'] = $return_deposit_fee;
                return $list;
            }
        } elseif ($data['type'] == "tiqian") {
            //提前还车时间
            $yq_time = bcmul($data['is_tq'], 86400);
            $yq_time = bcsub($orderInfo['end_time'], $yq_time);
            $return_time = $yq_time;
            $before_start_time = $return_time; // 提前开始时间（用户实际还车时间）
            $before_end_time = $orderInfo['end_time']; // 提前结束时间（订单结束时间）
            $before_car_fee = 0;
            if($orderInfo['shifu_car_fee']>0){
                $before_car_fee = $orderServices->carFee($orderInfo['type_id'], $before_start_time, $before_end_time); // 提前租车费
                if($orderInfo['coupon_user_id']>0){//用了优惠卷
                    $before_car_fee = bcdiv($orderInfo['shifu_car_fee'],$orderInfo['book_day'],2);
                    $before_car_fee = bcmul($before_car_fee,$data['is_tq'],2);
                }
            }

//            $before_base_service_fee = $orderServices->baseServiceFee($orderInfo['type_id'], $before_start_time, $before_end_time); // 提前基础服务费
//            $service = $orderServices->getcarService($orderInfo['type_id'], $before_start_time, $before_end_time);
//            $before_car_service_fee = 0;// 提前保险费
//            foreach ($service as $ser) {
//                if ($orderInfo['car_service_id']) {
//                    if ($ser['id'] == $orderInfo['car_service_id']) {
//                        $over_car_service_fee = $ser['price'];
//                        break;
//                    }
//                }
//            }
//                $before_return_fee = bcadd($before_car_fee, $before_base_service_fee);
            $return_deposit_fee = bcadd($orderInfo['deposit'], $before_car_fee, 2);
            $return_deposit_fee = bcsub($return_deposit_fee, $data['ss_car_price'], 2);//减去车损
            $list['over_return_fee'] = 0;//逾期还车的钱
            $list['early_return_fee'] = $before_car_fee;
            $list['ss_car_price'] = $data['ss_car_price'];
            $list['deposit'] = $orderInfo['deposit'];
            $list['return_deposit_fee'] = $return_deposit_fee;
            return $list;
        } else {
            $return_deposit_fee = bcsub($orderInfo['deposit'], 0, 2);
            $return_deposit_fee = bcsub($return_deposit_fee, $data['ss_car_price'], 2);
            $list['over_return_fee'] = 0;
            $list['early_return_fee'] = 0;
            $list['ss_car_price'] = $data['ss_car_price'];
            $list['deposit'] = $orderInfo['deposit'];
            $list['return_deposit_fee'] = $return_deposit_fee;
            return $list;
        }

    }

    /**
     * 获取最大逾期天数/提前还车天数
     * @param $data
     * @param $op_user
     * @param $op_user_type
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get_yq_tq_day($data, $op_user, $op_user_type)
    {
        /** @var CarOrderServices $orderServices */
        $orderServices = app()->make(CarOrderServices::class);
        $orderInfo = CarOrder::find($data['order_id']);
        $orderInfo = $orderInfo ? $orderInfo->toArray() : [];
        if (!$orderInfo) throw new ValidateException('未查询到订单信息');
        $CarType = CarType::find($orderInfo['type_id']);
        $CarType = $CarType ? $CarType->toArray() : [];
        $min = min($CarType['price'], $CarType['zhoumo_price']);
        $deposit = $orderInfo['deposit'];
        $day = (bcdiv($deposit, $min));
        $day = bcmul($day, 2);
        $arr = [];
        for ($i = 0; $i <= $day - 1; $i++) {
            $arr [] = 0.5 + $i * 0.5;
        }
        //租赁天数
        $tq_day = intval(($orderInfo['end_time'] - $orderInfo['start_time']) / 86400);
        if ($tq_day > 1) {
            $tq_day = $tq_day - 1;
        } else {
            $tq_day = 0;
        }
        $arr2 = [];
        if ($tq_day > 0) {
            for ($i = 1; $i <= $tq_day; $i++) {
                $arr2 [] = $i;
            }
        } else {
            $arr2 = [];
        }

        $list['yq'] = $arr;
        $list['tq'] = $arr2;
        return $list;
    }


    /**
     * 确认还车
     * @param $data
     * @param $op_user
     * @param $op_user_type
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function accomplishReturn($data, $op_user, $op_user_type)
    {
        /** @var CarOrderServices $orderServices */
        $orderServices = app()->make(CarOrderServices::class);
        $orderInfo = CarOrder::find($data['order_id']);
        $orderInfo = $orderInfo ? $orderInfo->toArray() : [];
        if (!$orderInfo) throw new ValidateException('未查询到订单信息');
        $return_time = strtotime($data['return_time']);
        $zl_day = intval(($orderInfo['end_time'] - $orderInfo['start_time']) / 86400);//租赁天数
        $check_yq = 0;
        // 判断用户是否超时还车
        if ($data['is_yq'] > 0) {
            $check_yq = 1;
        }
        if ($orderInfo['end_time'] < $return_time && $check_yq == 1) {
            $over_start_time = $orderInfo['end_time']; // 超时开始时间（订单结束时间）
            $over_end_time = $return_time;  // 超时结束时间（实际还车时间）
            $over_day = intval(($over_end_time - $over_start_time) / 86400);
            $over_day = $data['is_yq'];
//            $over_hour = round(($over_end_time - $over_start_time) % 86400 / 3600, 2);
            $over_hour = round(($over_end_time - $over_start_time) / 3600, 2);
            //逾期时间
            $yq_time = bcmul($data['is_yq'], 86400);
            $yq_time = bcadd($yq_time, $orderInfo['end_time']);
//            $over_car_fee = $orderServices->carFee2($orderInfo['type_id'], $over_start_time, $over_end_time, $over_hour, $data['is_yq']); // 超时租车费
            $over_car_fee = $orderServices->carFee3($orderInfo['type_id'], $over_start_time, $yq_time, $over_hour, $data['is_yq']); // 超时租车费 提前还车版本上的话用这段，注释上面！！！2024年5月31日13:28:22
            $over_base_service_fee = $orderServices->baseServiceFee($orderInfo['type_id'], $over_start_time, $over_end_time); // 超时基础服务费
            $service = $orderServices->getcarService($orderInfo['type_id'], $over_start_time, $over_end_time);
            $over_car_service_fee = 0;// 超时保险费
            foreach ($service as $ser) {
                if ($orderInfo['car_service_id']) {
                    if ($ser['id'] == $orderInfo['car_service_id']) {
                        $over_car_service_fee = $ser['price'];
                        break;
                    }
                }
            }
            $over_return_fee = bcadd($over_car_fee, $over_base_service_fee);
            $over_return_fee = bcadd($over_return_fee, $over_car_service_fee);
        } else {
            $over_start_time = $over_end_time = $over_hour = $over_day = $over_car_fee = $over_car_service_fee = $over_return_fee = $over_base_service_fee = 0;
        }
        // 判断用户是否提前还车
        if ($orderInfo['end_time'] > $return_time && $data['is_tq'] > 0) {
            if ($zl_day <= $data['is_tq']) throw new ValidateException('提前还车天数不能大于或等于总租赁天数');
//            $before_start_time = $return_time; // 提前开始时间（用户实际还车时间）
//            $before_end_time = $orderInfo['end_time']; // 提前结束时间（订单结束时间）
//            $before_day = intval(($before_end_time - $before_start_time) / 86400); // 提前天数
            $before_day = $data['is_tq'];//提前天数
            //提前还车时间
            $tq_time = bcmul($data['is_tq'], 86400);
            $tq_time = bcsub($orderInfo['end_time'], $tq_time);
            $return_time = $tq_time;
            $before_start_time = $return_time; // 提前开始时间（用户实际还车时间）
            $before_end_time = $orderInfo['end_time']; // 提前结束时间（订单结束时间）
            $before_car_fee = $orderServices->carFee($orderInfo['type_id'], $before_start_time, $before_end_time); // 提前租车费
            $before_base_service_fee = $orderServices->baseServiceFee($orderInfo['type_id'], $before_start_time, $before_end_time); // 提前基础服务费
            $service = $orderServices->getcarService($orderInfo['type_id'], $before_start_time, $before_end_time);
            $before_car_service_fee = 0;// 提前保险费
            foreach ($service as $ser) {
                if ($orderInfo['car_service_id']) {
                    if ($ser['id'] == $orderInfo['car_service_id']) {
                        $over_car_service_fee = $ser['price'];
                        break;
                    }
                }
            }
            $before_return_fee = 0;
            if($orderInfo['shifu_car_fee']>0){
                $before_return_fee = $before_car_fee;
                if($orderInfo['coupon_user_id']>0){//用了优惠卷
                    $before_return_fee = bcdiv($orderInfo['shifu_car_fee'],$orderInfo['book_day'],2);
                    $before_return_fee = bcmul($before_return_fee,$data['is_tq'],2);
                }
            }
//            $before_return_fee = bcadd($before_car_fee, $before_base_service_fee);//+基础服务费
//            $before_return_fee = bcadd($before_return_fee, $before_car_service_fee);//+保险费
        } else {
            $before_start_time = $before_end_time = $before_day = $before_car_fee = $before_base_service_fee = $before_car_service_fee = $before_return_fee = 0;
        }
        $insert = [
            'return_no' => $this->getReturnNo(),
            'return_staff_id' => $op_user['id'],
            'return_time' => $return_time,
            'return_pic_oil' => $data['return_pic_oil'],
//            'return_injury_item'=>$data['return_injury_item'],
//            'return_injury_pic'=>json_encode($data['return_injury_pic']),
            'return_oil_fee' => $data['return_oil_fee'],//油费
            'return_video' => $data['return_video'],
            'over_start_time' => $over_start_time,//超时开始日期时间
            'over_end_time' => $over_end_time,//超时结束日期时间
            'over_day' => $over_day,//超时天数
            'over_hour' => $over_hour,//超时小时数
            'over_car_fee' => $over_car_fee,
            'over_base_service_fee' => $over_base_service_fee,//超时基础服务费
            'car_service_id' => $orderInfo['car_service_id'] ? $orderInfo['car_service_id'] : '',//保险服务id
            'car_service_name' => $orderInfo['car_service_name'] ? $orderInfo['car_service_name'] : '',//保险服务名称
            'car_service_price' => $orderInfo['car_service_price'] ? $orderInfo['car_service_price'] : '',//保险价格/天
            'over_car_service_fee' => $over_car_service_fee,//超时保险费用
            'over_return_fee' => $over_return_fee,//超时还车费用
            'before_start_time' => $before_start_time,//提前开始日期时间
            'before_end_time' => $before_end_time,//提前结束日期时间
            'before_day' => $before_day,//提前天数
            'before_car_fee' => $before_car_fee,//提前租车费
            'before_base_service_fee' => $before_base_service_fee,//基础服务费
            'before_car_service_fee' => $before_car_service_fee,//保险费用
            'before_return_fee' => $before_return_fee,//提前还车返费用
            'deposit' => CarType::where('id', $orderInfo['type_id'])->value('deposit'),//车型押金
            'pay_all_fee' => $over_return_fee,//还车时需支付总价
            'refund_all_fee' => $before_return_fee,//还车时需退总金额
            'pay_fee' => $over_return_fee,//还车时需支付金额
//            'refund_fee' => bcadd($before_return_fee, $data['return_oil_fee']),
            'refund_fee' => $before_return_fee,//还车时需退金额
            'illegal_deposit' => CarType::where('id', $orderInfo['type_id'])->value('illegal_deposit'),
            'return_km' => $data['return_km'],
            'add_time' => time(),
            'damage_price' => '',
            'other_price' => '',
            'ss_car_array' => $data['ss_car_array'],
            'ss_car_price' => $data['ss_car_price'],
            'tui_car_fee_time' => time() + 86400,
            'tui_wz_fee_time' => time() + 1296000,
            'is_yq' => $data['is_yq'],
            'is_tq' => $data['is_tq'],
//            'store_id'=>$data['store_id']
        ];

        $this->transaction(function () use ($insert, $data, $op_user, $op_user_type, $orderInfo, $over_car_fee,$return_time) {
            if ($return_id = CarOrderReturn::insertGetId($insert)) {
                $res = CarOrder::where('id', $data['order_id'])->update(['return_id' => $return_id, 'status' => 30]);
                if (!$res) throw new ValidateException('订单回写失败');
                $car_id = CarOrderTake::where('id', $orderInfo['take_id'])->value('car_id');
                // 回写车辆公里数
                if ($car_id) CarInfo::where('id', $car_id)->update(['run_km' => $data['return_km']]);
                $title = '订单【' . CarOrder::where('id', $data['order_id'])->value('order_no') . '】完成还车';
                BaseLogServices::addLog($data['order_id'], 2, $title, $op_user_type, $op_user['id'], $op_user['user_name'], 6);
                //把车辆占用时间改了
                $occupy = Db::name('car_occupy_time')->where('order_id', $orderInfo["id"])->find();
                if ($occupy) {
                    Db::name('car_occupy_time')->where('order_id', $occupy['order_id'])->update(['end_time' => $return_time, 'remarks' => "用户提前还车", 'is_del' => 1]);
                }
                //订单信息有mchid的话就完成还车进行分账
                if ($orderInfo['mchid']) {
                    $fz = new SampleController();
                    $amount = $orderInfo['shifu_car_fee'];//实际付租车费
                    if ($amount > 0.2 && $orderInfo['mchid'] != '1463846202') {
                        $ok = $fz->divide($orderInfo);
                        if (isset($ok['state'])) {
                            if ($ok['state'] == 'PROCESSING' || $ok['state'] == 'FINISHED') {
                                $fzq = $orderInfo['shifu_car_fee'] * 0.1;
                                $msg = $orderInfo['order_no'] . '订单进行分账' . $fzq . "元|分账状态：" . $ok['state'];
                                BaseLogServices::addLog($data['order_id'], 2, $msg, $op_user_type, $op_user['id'], $op_user['user_name'], 27);
                                BaseLogServices::add_order_fz_flow($orderInfo, $msg, $fzq);
                            }
                        } else {
                            $error = [
                                'order_id' => $orderInfo['id'],
                                'order_no' => $orderInfo['order_no'],
                                'message' => $ok['message'],
                                'add_time' => time(),
                            ];
                            Db::name('order_fz_error')->insert($error);
                        }
                    } else {
                        $msg = $orderInfo['order_no'] . '订单车租金用户实际支付小于0.2，不进行分账';
                        BaseLogServices::addLog($data['order_id'], 2, $msg, $op_user_type, $op_user['id'], $op_user['user_name'], 27);
                    }
                    //完成还车直接退还用户车辆押金
//                    $tui = bcsub($orderInfo['deposit'],$data['ss_car_price'],2);//记录用
//                    $tui_fee = bcsub($orderInfo['deposit'],$data['ss_car_price'],2);//车辆押金
//                    if($over_car_fee>0){//如果有超时费就减去超时费退
//                        $tui_fee = bcsub($tui_fee,$over_car_fee,2);
//                        $tui = bcsub($tui,$over_car_fee,2);//记录用
//                    }
//                $log = "车损扣款：".$data['ss_car_price'].",超时退款：".$over_car_fee;
//                $tui_fee = $tui_fee*100;
//                $k_amount = bcadd($data['ss_car_price'],$over_car_fee);
//                $totalFee = $orderInfo['price']*100;//订单总金额
//                $out_refund_no = "deposit".$orderInfo['order_no'];//系统内部退款订单号，这里用deposit标识是车辆押金加上订单号
//                    $wxpay = new WxPayController();
//                    if($orderInfo['mchid']=='1463846202'){
//                        $refundData = [
//                            'pay_price'=>$orderInfo['price'],//订单总价
//                            'refund_price'=>$tui,//要退的钱
//                            'refund_no'=>$out_refund_no,//退款单号
//                            'type'=>'trade_no',//退款类型
//                            'refund_id'=>$out_refund_no,//这才是真正的退款单号
//                            'order_id'=>$orderInfo['id']
//                        ];
//                        $ok2 = MiniProgramService::payOrderRefund2($orderInfo['out_trade_no'], $refundData);//小程序
//                        if($ok2->return_code=="SUCCESS"&&$ok2->return_msg=="OK"){
//                            $ok2['code']  = 1;
//                        }
//                    }else{
//                        $ok2 = $wxpay->wx_refund($orderInfo['out_trade_no'],0,$totalFee,$tui_fee,0,0,0,$out_refund_no);
//                    }
//                    if($ok2['code']==1){
//                    Db::name('car_order')->where('id',$orderInfo['id'])->update(['it_deposit'=>1]);
//                    $tui_fee = $tui_fee/100;
//                    $msg = $orderInfo['order_no'].'订单用户进行还车，退车辆押金'.$tui_fee."元";
//                    BaseLogServices::addLog($data['order_id'],2,$msg,$op_user_type,$op_user['id'],$op_user['user_name'],28);
//                    BaseLogServices::add_deposit_Log($orderInfo['id'],$orderInfo['order_no'],1,$orderInfo['deposit'],$tui,$k_amount,$log,$orderInfo['store_id'],$data['ss_car_price'],$over_car_fee);
//                    }
                    //完成还车直接退还用户车辆押金

                }

            } else {
                throw new ValidateException('还车信息创建失败');
            }
        });
        return '提交成功';
    }
}
